unit database_system;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  Buttons, database_base;

type

  { TDatabaseSystemFrame }

  TDatabaseSystemFrame = class(TDatabaseBaseFrame)
    AirshipButton: TButton;
    AirshipLabel: TLabel;
    AirshipPanel: TPanel;
    AirshipSpeedButton: TSpeedButton;
    BoatButton: TButton;
    BoatLabel: TLabel;
    BoatPanel: TPanel;
    BoatSpeedButton: TSpeedButton;
    ChangeWindowColourButton: TButton;
    MenuCommandsCheckGroup: TCheckGroup;
    OptionsCheckGroup: TCheckGroup;
    GameTitleEdit: TEdit;
    CurrencyEdit: TEdit;
    GameTitleGroupBox: TGroupBox;
    CurrencyGroupBox: TGroupBox;
    VehicleImagesScrollBox: TScrollBox;
    ShipButton: TButton;
    ShipLabel: TLabel;
    ShipPanel: TPanel;
    ShipSpeedButton: TSpeedButton;
    VehicleImagesFlowPanel: TFlowPanel;
    WindowColourGroupBox: TGroupBox;
    WindowColourPaintBox: TPaintBox;
    VehicleImagesGroupBox: TGroupBox;
    SystemScrollBox: TScrollBox;

    procedure AirshipButtonClick(Sender: TObject);
    procedure BoatButtonClick(Sender: TObject);
    procedure ChangeWindowColourButtonClick(Sender: TObject);
    procedure CurrencyEditChange(Sender: TObject);
    procedure GameTitleEditChange(Sender: TObject);
    procedure Init; override;
    procedure MenuCommandsCheckGroupItemClick(Sender: TObject; Index: integer);
    procedure OptionsCheckGroupItemClick(Sender: TObject; Index: integer);
    procedure ShipButtonClick(Sender: TObject);
    procedure WindowColourPaintBoxDblClick(Sender: TObject);
    procedure WindowColourPaintBoxPaint(Sender: TObject);
  private
    IsLoading: Boolean;

    procedure FillOptionNames;
    procedure FillMenuCommandNames;
    procedure SetCheckboxesFromDb;
    procedure InitialSetUp;
    procedure UpdateVehicleImages;
    procedure DoVehicleGraphicsClick(VehicleType: String; Btn: TSpeedButton);
  public

  end;

resourcestring
  SystemHeader = 'System';

  SystemOption_ShowFollowers = 'Show player''s followers';
  SystemOption_KnockoutBySlipDamage = 'Allow knockout by slip damage';
  SystemOption_KnockoutByFloorDamage = 'Knockout by floor damage';
  SystemOption_DisplayTp = 'Display TP in battle';
  SystemOption_ExpForReserveMembers = 'Give EXP to reserve members';


implementation

uses
  fpjson, globals, imageselection, windowskincolourformunit;

{$R *.lfm}

{ TDatabaseSystemFrame }

procedure TDatabaseSystemFrame.Init;
begin
  FillOptionNames;
  FillMenuCommandNames;

  IsLoading := True;
  InitialSetUp;
  IsLoading := False
end;

procedure TDatabaseSystemFrame.GameTitleEditChange(Sender: TObject);
begin
  if IsLoading then
    Exit;

  Db.System.Strings['gameTitle'] := GameTitleEdit.Text;
end;

procedure TDatabaseSystemFrame.CurrencyEditChange(Sender: TObject);
begin
  if IsLoading then
    Exit;

  Db.System.Strings['currencyUnit'] := CurrencyEdit.Text;
end;

procedure TDatabaseSystemFrame.BoatButtonClick(Sender: TObject);
begin
  DoVehicleGraphicsClick('boat', BoatSpeedButton);
end;

procedure TDatabaseSystemFrame.ChangeWindowColourButtonClick(Sender: TObject);
begin
  WindowSkinColourForm.ShowForWindowTone(Db.System.Arrays['windowTone']);
  if WindowSkinColourForm.ModalResult = mrOK then begin
    Db.System.Arrays['windowTone'] := WindowSkinColourForm.MakeResult;
    WindowColourPaintBox.Refresh;
  end;
  //TODO: actually apply
end;

procedure TDatabaseSystemFrame.AirshipButtonClick(Sender: TObject);
begin
  DoVehicleGraphicsClick('airship', AirshipSpeedButton);
end;

procedure TDatabaseSystemFrame.MenuCommandsCheckGroupItemClick(Sender: TObject;
  Index: integer);
var
  I: Integer;
  Commands: TJSONArray;
begin
  if IsLoading then
    Exit;

  Commands := Db.System.Arrays['menuCommands'];
  for I := 0 to 5 do begin
    Commands.Booleans[I] := MenuCommandsCheckGroup.Checked[I];
  end;
end;

procedure TDatabaseSystemFrame.OptionsCheckGroupItemClick(Sender: TObject;
  Index: integer);
var
  S: TJSONObject;
begin
  if IsLoading then
    Exit;

  S := Db.System;
  S.Booleans['optFollowers'] := OptionsCheckGroup.Checked[0];
  S.Booleans['optSlipDeath'] := OptionsCheckGroup.Checked[1];
  S.Booleans['optFloorDeath'] := OptionsCheckGroup.Checked[2];
  S.Booleans['optDisplayTp'] := OptionsCheckGroup.Checked[3];
  S.Booleans['optExtraExp'] := OptionsCheckGroup.Checked[4];
end;

procedure TDatabaseSystemFrame.ShipButtonClick(Sender: TObject);
begin
  DoVehicleGraphicsClick('ship', ShipSpeedButton);
end;

procedure TDatabaseSystemFrame.WindowColourPaintBoxDblClick(Sender: TObject);
begin
  ChangeWindowColourButton.Click;
end;

procedure TDatabaseSystemFrame.WindowColourPaintBoxPaint(Sender: TObject);
var
  Tone: TJSONArray;
begin
  {TODO: Change this to use windowskin}
  with WindowColourPaintBox.Canvas do begin
    if Db.System.Find('windowTone', Tone) and (Tone.Count >= 3) then begin
      Brush.Color := RGBToColor(
                  Byte((Tone.Integers[0] + 128) div 2),
                  Byte((Tone.Integers[1] + 128) div 2),
                  Byte((Tone.Integers[2] + 128) div 2)
      );
    end else
        Brush.Color := clBtnFace;

    FillRect(0, 0, WindowColourPaintBox.Width, WindowColourPaintBox.Height);
  end;

end;

procedure TDatabaseSystemFrame.FillOptionNames;
begin
  with OptionsCheckGroup.Items do begin
    BeginUpdate;

    Clear;
    Add(SystemOption_ShowFollowers);
    Add(SystemOption_KnockoutBySlipDamage);
    Add(SystemOption_KnockoutByFloorDamage);
    Add(SystemOption_DisplayTp);
    Add(SystemOption_ExpForReserveMembers);

    EndUpdate;
  end;
end;

procedure TDatabaseSystemFrame.FillMenuCommandNames;
var
  CommandTerms: TJSONArray;
begin
  CommandTerms := Db.System.Objects['terms'].Arrays['commands'];

  with MenuCommandsCheckGroup.Items do begin
    BeginUpdate;

    Clear;
    Add(CommandTerms.Strings[4]); {Item}
    Add(CommandTerms.Strings[7]); {Status}
    Add(CommandTerms.Strings[5]); {Skill}
    Add(CommandTerms.Strings[8]); {Formation}
    Add(CommandTerms.Strings[6]); {Equip}
    Add(CommandTerms.Strings[9]); {Save}

    EndUpdate;
  end;
end;

procedure TDatabaseSystemFrame.SetCheckboxesFromDb;
  procedure SetOptions;
  var
    S: TJSONObject;
  begin
    S := Db.System;
    OptionsCheckGroup.Checked[0] := S.Booleans['optFollowers'];
    OptionsCheckGroup.Checked[1] := S.Booleans['optSlipDeath'];
    OptionsCheckGroup.Checked[2] := S.Booleans['optFloorDeath'];
    OptionsCheckGroup.Checked[3] := S.Booleans['optDisplayTp'];
    OptionsCheckGroup.Checked[4] := S.Booleans['optExtraExp'];

    {optDrawTitle, optTransparent, optSideView are in other sections}
  end;

  procedure SetCommands;
  var
    I: Integer;
    Commands: TJSONArray;
  begin
    Commands := Db.System.Arrays['menuCommands'];
    for I := 0 to 5 do begin
      MenuCommandsCheckGroup.Checked[I] := Commands.Booleans[I];
    end;
  end;

begin
  SetOptions;
  SetCommands
end;

procedure TDatabaseSystemFrame.InitialSetUp;
var
  Title: String = '';
  Currency: String = '';
  TitleJson: TJSONString = nil;
  CurrencyJson: TJSONString = nil;
begin
  if Db.System.Find('gameTitle', TitleJson) then
    Title := TitleJson.AsString;
  GameTitleEdit.Text := Title;

  if Db.System.Find('currencyUnit', CurrencyJson) then
    Currency := CurrencyJson.AsString;
  CurrencyEdit.Text := Currency;

  SetCheckboxesFromDb;
  UpdateVehicleImages
end;

procedure TDatabaseSystemFrame.UpdateVehicleImages;
  procedure UpdateVehicleImage(VehicleType: String; Btn: TSpeedButton);
  var
    Vehicle: TJSONObject;
    CharName: TJSONString = nil;
    CharIndex: TJSONNumber = nil;
    VehiclePng: TBitmap;
  begin
    Btn.Glyph.Clear;

    if not Db.System.Find(VehicleType, Vehicle) then begin
      Exit;
    end;

    if Vehicle.Find('characterName', CharName)
               and Vehicle.Find('characterIndex', CharIndex) then begin
       VehiclePng := Game.GetCharacterGraphics(CharName.AsString,
                                               CharIndex.AsInteger);
       Btn.Glyph.Assign(VehiclePng);
       VehiclePng.Free;
    end;
  end;

begin
  UpdateVehicleImage('boat', BoatSpeedButton);
  UpdateVehicleImage('ship', ShipSpeedButton);
  UpdateVehicleImage('airship', AirshipSpeedButton);
end;

procedure TDatabaseSystemFrame.DoVehicleGraphicsClick(VehicleType: String;
  Btn: TSpeedButton);
var
  Vehicle: TJSONObject;
  CharName: TJSONString = nil;
  CharIndex: TJSONNumber = nil;
  VehiclePng: TBitmap;
begin
  if not Db.System.Find(VehicleType, Vehicle) then begin
    Exit;
  end;

  if Vehicle.Find('characterName', CharName)
             and Vehicle.Find('characterIndex', CharIndex) then begin

     if ImageSelectionForm.ShowSimpleCharSelection(CharName.AsString,
                                                 CharIndex.AsInteger) then begin
       Vehicle.Strings['characterName'] := ImageSelectionForm.SelectedFilename;
       Vehicle.Integers['characterIndex'] := ImageSelectionForm.Index;
       UpdateVehicleImages;
     end;
  end;

  {TODO}
end;

end.

